﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="CollectionChangeUndoEvent.cs" >
//   J. Prinz
// </copyright>
// <summary>
//   A CollectionChangeUndoEvent holds all data to redo and undo ListChanges
//   that are ItemDeleted and ItemAdded Commands
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace AutomationMLMapper.Utilities
{
    using System.Collections;
    using System.ComponentModel;

    /// <summary>
    ///   A CollectionChangeUndoEvent holds all data to redo and undo ListChanges
    ///   that are ItemDeleted and ItemAdded Commands
    /// </summary>
    public class CollectionChangeUndoEvent : IUndoEvent
    {
        #region Fields

        /// <summary>
        /// modification operation, performed on the list
        /// </summary>
        private readonly ListChangedType listChangeOperation;

        /// <summary>
        /// index of element to be changed
        /// </summary>
        private readonly int index;

        /// <summary>
        ///  the List
        /// </summary>
        private readonly IList target;

        /// <summary>
        ///  changed object
        /// </summary>
        private readonly object value;

        #endregion

        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="CollectionChangeUndoEvent"/> class. 
        /// </summary>
        /// <param name="target">
        /// The changed list
        /// </param>
        /// <param name="listChangeOperation">
        /// The List Change Operation. 
        /// </param>
        /// <param name="index">
        /// The index of the item. 
        /// </param>
        /// <param name="value">
        /// The value 
        /// </param>
        public CollectionChangeUndoEvent(IList target, ListChangedType listChangeOperation, int index, object value)
        {
            this.target = target;
            this.listChangeOperation = listChangeOperation;
            this.value = value;
            this.index = index;
        }

        #endregion

        #region Public Methods and Operators

        /// <summary>
        /// Redo last undone change
        /// </summary>
        public void Redo()
        {
            switch (this.listChangeOperation)
            {
                case ListChangedType.ItemAdded:
                    this.target.Insert(this.index, this.value);
                    break;

                case ListChangedType.ItemDeleted:
                    this.target.Remove(this.value);
                    break;

                case ListChangedType.ItemChanged:
                    this.target.RemoveAt(this.index);
                    this.target.Insert(this.index, this.value);
                    break;
            }
        }

        /// <summary>
        /// Undo last change
        /// </summary>
        public void Undo()
        {
            switch (this.listChangeOperation)
            {
                case ListChangedType.ItemAdded:
                    this.target.Remove(this.value);
                    break;

                case ListChangedType.ItemDeleted:
                    this.target.Insert(this.index, this.value);
                    break;

                case ListChangedType.ItemChanged:
                    this.target.RemoveAt(this.index);
                    this.target.Insert(this.index, this.value);
                    break;
            }
        }

        #endregion
    }
}